Completed
Push — master ( 5f62fb...1a8fc1 )
by Mark
16s queued 12s
created

Collection.merge   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
/**
2
 *
3
 */
4
export default class Collection extends Array {
5
6
    constructor(...items) {
7
        super(...items);
8
    }
9
10
    get operators() {
11
        return {
12
            '>'(fieldValue, value) {
13
                return fieldValue > value;
14
            },
15
            '>='(fieldValue, value) {
16
                return fieldValue >= value;
17
            },
18
            '<'(fieldValue, value) {
19
                return fieldValue < value;
20
            },
21
            '<='(fieldValue, value) {
22
                return fieldValue <= value;
23
            },
24
            '!='(fieldValue, value) {
25
                return fieldValue != value;
26
            },
27
            '=='(fieldValue, value) {
28
                return fieldValue == value;
29
            }
30
        }
31
    }
32
33
    first() {
34
        return this[0] ?? null;
35
    }
36
37
    jsonStringify(): string {
38
        return JSON.stringify(this);
39
    }
40
41
    last() {
42
        return this.slice(-1)[0] ?? null;
43
    }
44
45
    merge(array): Collection {
46
        this.push(...array);
47
        return this;
48
    }
49
50
    pluck(field: string, keyField = '') {
51
        const lookUpFields = field.split('.');
52
53
        if (keyField) {
54
            const lookUpKeyField = keyField.split('.');
55
            const result = {};
56
            for (const i in this) {
57
                result[this._getRowFieldResult(this[i], lookUpKeyField)] = this._getRowFieldResult(this[i], lookUpFields);
58
            }
59
            return result;
60
        }
61
62
        const result = [];
63
        for (const i in this) {
64
            result.push(this._getRowFieldResult(this[i], lookUpFields));
65
        }
66
67
        return result;
68
    }
69
70
    random() {
71
        return this[Math.round(((this.length - 1) * Math.random()))];
72
    }
73
74
    unique(field: string): Collection {
75
        const unique = {};
76
        for (const i in this) {
77
            unique[this[i][field]] = this[i];
78
        }
79
80
        return new Collection(...Object.values(unique));
81
    }
82
83
    where(field: string, operator: string, value = null): Collection {
84
        value = value ?? operator;
85
        operator = (operator === value) ? '==' : operator;
86
87
        if (!Object.prototype.hasOwnProperty.call(this.operators, operator)) {
88
            throw new Error("Invalid comparison operator used");
89
        }
90
91
        return this.whereIfFunction(field, (field, object) => {
92
            return this.operators[operator](object[field], value);
93
        })
94
    }
95
96
    whereBetween(field: string, values): Collection {
97
        return this.whereIfFunction(field, (field, object) => {
98
            const fieldValue = object[field];
99
            return fieldValue >= values[0] && fieldValue <= values[1]
100
        });
101
    }
102
103
    whereIfFunction(field: string, whereIfFunction: CallableFunction): Collection {
104
        const register = new Collection();
105
        for (const i in this) {
106
            if (whereIfFunction(field, this[i])) {
107
                register.push(this[i]);
108
            }
109
        }
110
        return register;
111
    }
112
113
    whereIn(field: string, values): Collection {
114
        return this.whereIfFunction(field, (field, object) => {
115
            return values.includes(object[field]);
116
        });
117
    }
118
119
    whereInstanceOf(classInstance): Collection {
120
        return this.whereIfFunction(null, (field, object) => {
121
            return object instanceof classInstance;
122
        });
123
    }
124
125
    whereNotBetween(field: string, values): Collection {
126
        return this.whereIfFunction(field, (field, object) => {
127
            const fieldValue = object[field];
128
            return !(fieldValue >= values[0] && fieldValue <= values[1])
129
        });
130
    }
131
132
    whereNotIn(field: string, values): Collection {
133
        return this.whereIfFunction(field, (field, object) => {
134
            return !values.includes(object[field]);
135
        });
136
    }
137
138
    whereNotInstanceOf(classInstance): Collection {
139
        return this.whereIfFunction(null, (field, object) => {
140
            return !(object instanceof classInstance);
141
        });
142
    }
143
144
    whereNotNull(field: string): Collection {
145
        return this.whereIfFunction(field, (field, object) => {
146
            return object[field] !== null;
147
        });
148
    }
149
150
    whereNull(field: string): Collection {
151
        return this.whereIfFunction(field, (field, object) => {
152
            return object[field] === null;
153
        });
154
    }
155
156
    private _getRowFieldResult(row, lookUpFields) {
157
        let resultField = row[lookUpFields[0]] ?? null;
158
        for (let i = 1; i < lookUpFields.length; i++) {
159
            const currentField = lookUpFields[i];
160
161
            if (resultField === null) {
162
                break;
163
            }
164
165
            if (resultField instanceof Collection) {
166
                return resultField.pluck(lookUpFields[i]);
167
            }
168
169
            resultField = resultField[currentField] ?? null;
170
        }
171
172
        return resultField;
173
    }
174
}